package com.suse.warmstill.autho;

import com.alibaba.fastjson.JSON;
import com.suse.warmstill.common.enums.ResponseEnum;
import com.suse.warmstill.common.exception.BusinessException;
import com.suse.warmstill.common.exception.SystemException;
import com.suse.warmstill.common.model.CallResult;
import com.suse.warmstill.common.utils.IpUtils;
import com.suse.warmstill.common.utils.JwtUtil;
import com.suse.warmstill.common.utils.RedisCache;
import com.suse.warmstill.common.utils.UserIdThreadLocal;
import com.suse.warmstill.service.TokenService;
import com.suse.warmstill.service.repository.TokenRepository;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.time.LocalDateTime;
import java.util.Arrays;

/**
 * @author 黄靖
 * @author 2022-10-28 01:54
 * description:
 **/
@Component
@Slf4j
public class JwtIntercepter implements HandlerInterceptor {
    @Autowired
    private TokenRepository tokenRepository;

    @Autowired
    private TokenService tokenService;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        final String ipAddr = IpUtils.getIpAddr(request);
        final String path = request.getRequestURI().toString();
        String token = null;
        final Cookie[] cookies = request.getCookies();

        if (ObjectUtils.isNotEmpty(cookies)) {
            for (Cookie cookie : cookies
            ) {

                if ("accessToken".equals(cookie.getName())) {
                    if (StringUtils.isEmpty(cookie.getValue())) {
                        log.error("cookie中 无数据");
                        returnJson(response);
                        return false;
                    }
                    token = cookie.getValue();
                    break;
                }

            }
        }
        if (ObjectUtils.isEmpty(token)) {
            token = request.getHeader("accessToken");
        }

        if (StringUtils.isEmpty(token)) {
            log.error("未能从 header 或者 cookie 获取 token！");
            returnJson(response);
            return false;
        }

        Long userId = tokenService.checkToken(token);
        log.info("requestUserId =====>{},requestURL==========> {},requestTime===>{}", userId, path, LocalDateTime.now());


        if (ObjectUtils.isEmpty(userId)) {
            log.error("请求ip {},登入错误", ipAddr);
            returnJson(response);
            return false;

        }


        /*
         * 如果redis中的token 为空 或者 两个token不相同
         * */


        /*
         * 存储用户的Id
         * */
        UserIdThreadLocal.put(userId);

        return true;
    }


    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        UserIdThreadLocal.remove();


        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }


    private void returnJson(HttpServletResponse response) {
        PrintWriter writer = null;
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        try {
            writer = response.getWriter();
            CallResult callResult = CallResult.fail(ResponseEnum.NO_LOGIN.getCode(), "您的登录非法，请重新登录");
            writer.print(JSON.toJSONString(callResult));
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (writer != null) {
                writer.close();
            }
        }
    }
}
